package com.hqd.ch03.v49.utils;

import com.hqd.ch03.v49.beans.BeansException;
import com.hqd.ch03.v49.factory.BeanFactory;
import com.hqd.ch03.v49.factory.ListableBeanFactory;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class BeanFactoryUtils {
    private static final Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();

    public static String[] beanNamesForTypeIncludingAncestors(
            ListableBeanFactory beanFactory, Class<?> type) {
        return beanFactory.getBeanNamesForType(type);
    }

    public static <T> Map<String, T> beansOfTypeIncludingAncestors(
            ListableBeanFactory lbf, Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
            throws BeansException {

        Map<String, T> result = new LinkedHashMap<>(4);
        String[] beanNamesForType = lbf.getBeanNamesForType(type);
        for (String bnft : beanNamesForType) {
            result.put(bnft, (T) lbf.getBean(bnft));
        }
        return result;
    }

    public static String transformedBeanName(String name) {
        if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
            return name;
        }
        return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
            do {
                beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
            }
            while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
            return beanName;
        });
    }
}
